//! GraphQL查询处理器
//! 
//! 提供GraphQL查询解析、验证和执行功能

use std::collections::HashMap;
use async_trait::async_trait;
use serde_json::{Value, json};
use anyhow::{Result, anyhow};

/// GraphQL查询类型
#[derive(Debug, Clone, PartialEq)]
pub enum GraphQLOperationType {
    Query,
    Mutation,
    Subscription,
}

/// GraphQL字段
#[derive(Debug, Clone)]
pub struct GraphQLField {
    /// 字段名称
    pub name: String,
    /// 字段别名
    pub alias: Option<String>,
    /// 字段参数
    pub arguments: HashMap<String, Value>,
    /// 子字段
    pub selection_set: Vec<GraphQLField>,
}

/// GraphQL查询
#[derive(Debug, Clone)]
pub struct GraphQLQuery {
    /// 操作类型
    pub operation_type: GraphQLOperationType,
    /// 操作名称
    pub operation_name: Option<String>,
    /// 变量定义
    pub variables: HashMap<String, Value>,
    /// 选择集
    pub selection_set: Vec<GraphQLField>,
}

/// GraphQL查询结果
#[derive(Debug, Clone)]
pub struct GraphQLResult {
    /// 查询数据
    pub data: Option<Value>,
    /// 错误信息
    pub errors: Vec<GraphQLError>,
    /// 扩展信息
    pub extensions: Option<Value>,
}

/// GraphQL错误
#[derive(Debug, Clone)]
pub struct GraphQLError {
    /// 错误消息
    pub message: String,
    /// 错误位置
    pub locations: Vec<GraphQLLocation>,
    /// 错误路径
    pub path: Option<Vec<String>>,
    /// 扩展信息
    pub extensions: Option<Value>,
}

/// GraphQL位置信息
#[derive(Debug, Clone)]
pub struct GraphQLLocation {
    /// 行号
    pub line: usize,
    /// 列号
    pub column: usize,
}

/// GraphQL解析器
pub struct GraphQLParser {
    /// 解析器状态
    position: usize,
    /// 输入文本
    input: String,
}

impl GraphQLParser {
    /// 创建新的GraphQL解析器
    pub fn new() -> Self {
        Self {
            position: 0,
            input: String::new(),
        }
    }

    /// 解析GraphQL查询
    pub fn parse(&mut self, query: &str) -> Result<GraphQLQuery> {
        self.input = query.to_string();
        self.position = 0;

        // 跳过空白字符
        self.skip_whitespace();

        // 解析操作类型
        let operation_type = self.parse_operation_type()?;
        
        // 解析操作名称（可选）
        let operation_name = self.parse_operation_name();

        // 解析变量定义（可选）
        let variables = self.parse_variables()?;

        // 解析选择集
        let selection_set = self.parse_selection_set()?;

        Ok(GraphQLQuery {
            operation_type,
            operation_name,
            variables,
            selection_set,
        })
    }

    /// 解析操作类型
    fn parse_operation_type(&mut self) -> Result<GraphQLOperationType> {
        self.skip_whitespace();
        
        if self.peek_word("query") {
            self.consume_word("query");
            Ok(GraphQLOperationType::Query)
        } else if self.peek_word("mutation") {
            self.consume_word("mutation");
            Ok(GraphQLOperationType::Mutation)
        } else if self.peek_word("subscription") {
            self.consume_word("subscription");
            Ok(GraphQLOperationType::Subscription)
        } else {
            // 默认为查询
            Ok(GraphQLOperationType::Query)
        }
    }

    /// 解析操作名称
    fn parse_operation_name(&mut self) -> Option<String> {
        self.skip_whitespace();
        
        if self.current_char().map_or(false, |c| c.is_alphabetic()) {
            Some(self.parse_name())
        } else {
            None
        }
    }

    /// 解析变量定义
    fn parse_variables(&mut self) -> Result<HashMap<String, Value>> {
        let mut variables = HashMap::new();

        self.skip_whitespace();
        if self.current_char() == Some('(') {
            self.advance(); // 消费 '('

            while self.current_char() != Some(')') && !self.is_at_end() {
                self.skip_whitespace();

                // 跳过空白字符和逗号
                if self.current_char() == Some(',') {
                    self.advance();
                    self.skip_whitespace();
                    continue;
                }

                if self.current_char() == Some(')') {
                    break;
                }

                // 解析变量名
                if self.current_char() != Some('$') {
                    // 如果没有变量，直接跳出
                    break;
                }
                self.advance(); // 消费 '$'

                let var_name = self.parse_name();

                self.skip_whitespace();
                if self.current_char() != Some(':') {
                    return Err(anyhow!("Expected ':' after variable name"));
                }
                self.advance(); // 消费 ':'

                // 解析变量类型（简化处理）
                self.skip_whitespace();
                let _var_type = self.parse_type();

                // 解析默认值（可选）
                self.skip_whitespace();
                let default_value = if self.current_char() == Some('=') {
                    self.advance(); // 消费 '='
                    self.parse_value()?
                } else {
                    Value::Null
                };

                variables.insert(var_name, default_value);

                self.skip_whitespace();
                if self.current_char() == Some(',') {
                    self.advance(); // 消费 ','
                }
            }

            if self.current_char() == Some(')') {
                self.advance(); // 消费 ')'
            }
        }

        Ok(variables)
    }

    /// 解析类型
    fn parse_type(&mut self) -> String {
        let mut type_name = self.parse_name();

        // 处理非空类型 (!)
        if self.current_char() == Some('!') {
            type_name.push('!');
            self.advance();
        }

        type_name
    }

    /// 解析选择集
    fn parse_selection_set(&mut self) -> Result<Vec<GraphQLField>> {
        let mut fields = Vec::new();
        
        self.skip_whitespace();
        if self.current_char() != Some('{') {
            return Err(anyhow!("Expected '{{' to start selection set"));
        }
        self.advance(); // 消费 '{'
        
        while self.current_char() != Some('}') && !self.is_at_end() {
            self.skip_whitespace();
            
            let field = self.parse_field()?;
            fields.push(field);
            
            self.skip_whitespace();
            if self.current_char() == Some(',') {
                self.advance(); // 消费 ','
            }
        }
        
        if self.current_char() == Some('}') {
            self.advance(); // 消费 '}'
        }
        
        Ok(fields)
    }

    /// 解析字段
    fn parse_field(&mut self) -> Result<GraphQLField> {
        self.skip_whitespace();
        
        let name = self.parse_name();
        let mut alias = None;
        let mut field_name = name.clone();
        
        // 检查是否有别名
        self.skip_whitespace();
        if self.current_char() == Some(':') {
            self.advance(); // 消费 ':'
            alias = Some(name);
            self.skip_whitespace();
            field_name = self.parse_name();
        }
        
        // 解析参数
        let arguments = self.parse_arguments()?;
        
        // 解析子选择集
        let selection_set = if self.current_char() == Some('{') {
            self.parse_selection_set()?
        } else {
            Vec::new()
        };
        
        Ok(GraphQLField {
            name: field_name,
            alias,
            arguments,
            selection_set,
        })
    }

    /// 解析参数
    fn parse_arguments(&mut self) -> Result<HashMap<String, Value>> {
        let mut arguments = HashMap::new();

        self.skip_whitespace();
        if self.current_char() == Some('(') {
            self.advance(); // 消费 '('

            while self.current_char() != Some(')') && !self.is_at_end() {
                self.skip_whitespace();

                // 跳过空白字符和逗号
                if self.current_char() == Some(',') {
                    self.advance();
                    self.skip_whitespace();
                    continue;
                }

                if self.current_char() == Some(')') {
                    break;
                }

                let arg_name = self.parse_name();

                self.skip_whitespace();
                if self.current_char() != Some(':') {
                    return Err(anyhow!("Expected ':' after argument name"));
                }
                self.advance(); // 消费 ':'

                self.skip_whitespace();
                let arg_value = self.parse_value()?;

                arguments.insert(arg_name, arg_value);

                self.skip_whitespace();
                if self.current_char() == Some(',') {
                    self.advance(); // 消费 ','
                }
            }

            if self.current_char() == Some(')') {
                self.advance(); // 消费 ')'
            }
        }

        Ok(arguments)
    }

    /// 解析值
    fn parse_value(&mut self) -> Result<Value> {
        self.skip_whitespace();
        
        match self.current_char() {
            Some('"') => {
                // 字符串值
                self.advance(); // 消费 '"'
                let mut value = String::new();
                while self.current_char() != Some('"') && !self.is_at_end() {
                    if let Some(c) = self.current_char() {
                        value.push(c);
                        self.advance();
                    }
                }
                if self.current_char() == Some('"') {
                    self.advance(); // 消费 '"'
                }
                Ok(Value::String(value))
            }
            Some(c) if c.is_ascii_digit() || c == '-' => {
                // 数字值
                let mut value = String::new();
                if self.current_char() == Some('-') {
                    value.push('-');
                    self.advance();
                }
                while self.current_char().map_or(false, |c| c.is_ascii_digit() || c == '.') {
                    if let Some(c) = self.current_char() {
                        value.push(c);
                        self.advance();
                    }
                }
                if value.contains('.') {
                    Ok(Value::Number(serde_json::Number::from_f64(value.parse::<f64>()?).unwrap()))
                } else {
                    Ok(Value::Number(serde_json::Number::from(value.parse::<i64>()?)))
                }
            }
            Some('t') if self.peek_word("true") => {
                self.consume_word("true");
                Ok(Value::Bool(true))
            }
            Some('f') if self.peek_word("false") => {
                self.consume_word("false");
                Ok(Value::Bool(false))
            }
            Some('n') if self.peek_word("null") => {
                self.consume_word("null");
                Ok(Value::Null)
            }
            Some('$') => {
                // 变量引用
                self.advance(); // 消费 '$'
                let var_name = self.parse_name();
                Ok(Value::String(format!("${}", var_name)))
            }
            _ => {
                // 枚举值或标识符
                let name = self.parse_name();
                if name.is_empty() {
                    Ok(Value::Null)
                } else {
                    Ok(Value::String(name))
                }
            }
        }
    }

    /// 解析名称
    fn parse_name(&mut self) -> String {
        let mut name = String::new();
        while self.current_char().map_or(false, |c| c.is_alphanumeric() || c == '_') {
            if let Some(c) = self.current_char() {
                name.push(c);
                self.advance();
            }
        }
        name
    }

    /// 跳过空白字符
    fn skip_whitespace(&mut self) {
        while self.current_char().map_or(false, |c| c.is_whitespace()) {
            self.advance();
        }
    }

    /// 获取当前字符
    fn current_char(&self) -> Option<char> {
        self.input.chars().nth(self.position)
    }

    /// 前进一个字符
    fn advance(&mut self) {
        if self.position < self.input.len() {
            self.position += 1;
        }
    }

    /// 检查是否到达末尾
    fn is_at_end(&self) -> bool {
        self.position >= self.input.len()
    }

    /// 检查是否匹配单词
    fn peek_word(&self, word: &str) -> bool {
        let remaining = &self.input[self.position..];
        remaining.starts_with(word) && 
            remaining.chars().nth(word.len()).map_or(true, |c| !c.is_alphanumeric())
    }

    /// 消费单词
    fn consume_word(&mut self, word: &str) {
        if self.peek_word(word) {
            self.position += word.len();
        }
    }
}

impl Default for GraphQLParser {
    fn default() -> Self {
        Self::new()
    }
}

/// GraphQL执行器
pub struct GraphQLExecutor {
    /// 数据源映射
    data_sources: HashMap<String, Box<dyn GraphQLDataSource>>,
}

/// GraphQL数据源trait
#[async_trait]
pub trait GraphQLDataSource: Send + Sync {
    /// 获取数据源名称
    fn name(&self) -> &str;

    /// 解析字段
    async fn resolve_field(&self, field: &GraphQLField, context: &GraphQLContext) -> Result<Value>;

    /// 获取Schema信息
    async fn get_schema(&self) -> Result<Value>;
}

/// GraphQL执行上下文
#[derive(Debug, Clone)]
pub struct GraphQLContext {
    /// 变量
    pub variables: HashMap<String, Value>,
    /// 请求信息
    pub request_info: HashMap<String, Value>,
}

impl GraphQLExecutor {
    /// 创建新的GraphQL执行器
    pub fn new() -> Self {
        Self {
            data_sources: HashMap::new(),
        }
    }

    /// 注册数据源
    pub fn register_data_source(&mut self, name: String, data_source: Box<dyn GraphQLDataSource>) {
        self.data_sources.insert(name, data_source);
    }

    /// 执行GraphQL查询
    pub async fn execute(&self, query: GraphQLQuery, context: GraphQLContext) -> GraphQLResult {
        let mut errors = Vec::new();

        match query.operation_type {
            GraphQLOperationType::Query => {
                match self.execute_query(query.selection_set, &context).await {
                    Ok(data) => GraphQLResult {
                        data: Some(data),
                        errors,
                        extensions: None,
                    },
                    Err(e) => {
                        errors.push(GraphQLError {
                            message: e.to_string(),
                            locations: vec![],
                            path: None,
                            extensions: None,
                        });
                        GraphQLResult {
                            data: None,
                            errors,
                            extensions: None,
                        }
                    }
                }
            }
            GraphQLOperationType::Mutation => {
                // TODO: 实现Mutation执行
                errors.push(GraphQLError {
                    message: "Mutations not yet implemented".to_string(),
                    locations: vec![],
                    path: None,
                    extensions: None,
                });
                GraphQLResult {
                    data: None,
                    errors,
                    extensions: None,
                }
            }
            GraphQLOperationType::Subscription => {
                // TODO: 实现Subscription执行
                errors.push(GraphQLError {
                    message: "Subscriptions not yet implemented".to_string(),
                    locations: vec![],
                    path: None,
                    extensions: None,
                });
                GraphQLResult {
                    data: None,
                    errors,
                    extensions: None,
                }
            }
        }
    }

    /// 执行查询
    async fn execute_query(&self, selection_set: Vec<GraphQLField>, context: &GraphQLContext) -> Result<Value> {
        let mut result = serde_json::Map::new();

        for field in selection_set {
            let field_result = self.resolve_field(&field, context).await?;
            let field_name = field.alias.as_ref().unwrap_or(&field.name);
            result.insert(field_name.clone(), field_result);
        }

        Ok(Value::Object(result))
    }

    /// 解析字段
    async fn resolve_field(&self, field: &GraphQLField, context: &GraphQLContext) -> Result<Value> {
        // 根据字段名称路由到相应的数据源
        match field.name.as_str() {
            "users" | "user" => {
                if let Some(data_source) = self.data_sources.get("memory") {
                    data_source.resolve_field(field, context).await
                } else {
                    Ok(json!([]))
                }
            }
            "products" | "product" => {
                if let Some(data_source) = self.data_sources.get("memory") {
                    data_source.resolve_field(field, context).await
                } else {
                    Ok(json!([]))
                }
            }
            _ => {
                // 默认返回空值
                Ok(Value::Null)
            }
        }
    }
}

impl Default for GraphQLExecutor {
    fn default() -> Self {
        Self::new()
    }
}

/// 内存数据源的GraphQL适配器
pub struct MemoryGraphQLDataSource {
    /// 数据存储
    data: HashMap<String, Vec<HashMap<String, Value>>>,
}

impl MemoryGraphQLDataSource {
    /// 创建新的内存GraphQL数据源
    pub fn new() -> Self {
        let mut data = HashMap::new();

        // 添加示例用户数据
        let users = vec![
            [
                ("id".to_string(), json!(1)),
                ("name".to_string(), json!("张三")),
                ("email".to_string(), json!("zhangsan@example.com")),
                ("age".to_string(), json!(25)),
            ].iter().cloned().collect(),
            [
                ("id".to_string(), json!(2)),
                ("name".to_string(), json!("李四")),
                ("email".to_string(), json!("lisi@example.com")),
                ("age".to_string(), json!(30)),
            ].iter().cloned().collect(),
        ];
        data.insert("users".to_string(), users);

        // 添加示例产品数据
        let products = vec![
            [
                ("id".to_string(), json!(1)),
                ("name".to_string(), json!("笔记本电脑")),
                ("price".to_string(), json!(5999.99)),
                ("category".to_string(), json!("电子产品")),
            ].iter().cloned().collect(),
            [
                ("id".to_string(), json!(2)),
                ("name".to_string(), json!("智能手机")),
                ("price".to_string(), json!(2999.99)),
                ("category".to_string(), json!("电子产品")),
            ].iter().cloned().collect(),
        ];
        data.insert("products".to_string(), products);

        Self { data }
    }
}

#[async_trait]
impl GraphQLDataSource for MemoryGraphQLDataSource {
    fn name(&self) -> &str {
        "memory"
    }

    async fn resolve_field(&self, field: &GraphQLField, _context: &GraphQLContext) -> Result<Value> {
        match field.name.as_str() {
            "users" => {
                if let Some(users) = self.data.get("users") {
                    // 应用字段选择
                    let filtered_users: Vec<Value> = users.iter().map(|user| {
                        if field.selection_set.is_empty() {
                            // 返回所有字段
                            json!(user)
                        } else {
                            // 只返回选择的字段
                            let mut filtered_user = serde_json::Map::new();
                            for sub_field in &field.selection_set {
                                if let Some(value) = user.get(&sub_field.name) {
                                    filtered_user.insert(sub_field.name.clone(), value.clone());
                                }
                            }
                            Value::Object(filtered_user)
                        }
                    }).collect();
                    Ok(Value::Array(filtered_users))
                } else {
                    Ok(json!([]))
                }
            }
            "user" => {
                // 处理单个用户查询
                if let Some(id_arg) = field.arguments.get("id") {
                    if let Some(users) = self.data.get("users") {
                        if let Some(id) = id_arg.as_i64() {
                            for user in users {
                                if let Some(user_id) = user.get("id") {
                                    if user_id.as_i64() == Some(id) {
                                        return Ok(json!(user));
                                    }
                                }
                            }
                        }
                    }
                }
                Ok(Value::Null)
            }
            "products" => {
                if let Some(products) = self.data.get("products") {
                    Ok(json!(products))
                } else {
                    Ok(json!([]))
                }
            }
            _ => Ok(Value::Null),
        }
    }

    async fn get_schema(&self) -> Result<Value> {
        Ok(json!({
            "types": [
                {
                    "name": "User",
                    "fields": [
                        {"name": "id", "type": "Int"},
                        {"name": "name", "type": "String"},
                        {"name": "email", "type": "String"},
                        {"name": "age", "type": "Int"}
                    ]
                },
                {
                    "name": "Product",
                    "fields": [
                        {"name": "id", "type": "Int"},
                        {"name": "name", "type": "String"},
                        {"name": "price", "type": "Float"},
                        {"name": "category", "type": "String"}
                    ]
                }
            ]
        }))
    }
}

impl Default for MemoryGraphQLDataSource {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_graphql_parser_simple_query() {
        let mut parser = GraphQLParser::new();
        let query = r#"
            query {
                users {
                    id
                    name
                    email
                }
            }
        "#;

        let result = parser.parse(query).unwrap();
        assert_eq!(result.operation_type, GraphQLOperationType::Query);
        assert_eq!(result.selection_set.len(), 1);
        assert_eq!(result.selection_set[0].name, "users");
        assert_eq!(result.selection_set[0].selection_set.len(), 3);
    }

    #[test]
    fn test_graphql_parser_query_with_arguments() {
        let mut parser = GraphQLParser::new();
        let query = r#"query { user(id: 1) { name } }"#;

        let result = parser.parse(query).unwrap();
        assert_eq!(result.operation_type, GraphQLOperationType::Query);
        // 基本解析成功即可
        assert!(!result.selection_set.is_empty());
        assert_eq!(result.selection_set[0].name, "user");
    }

    #[test]
    fn test_graphql_parser_mutation() {
        let mut parser = GraphQLParser::new();
        let query = r#"mutation { createUser(name: "test") { id } }"#;

        let result = parser.parse(query).unwrap();
        assert_eq!(result.operation_type, GraphQLOperationType::Mutation);
        // 基本解析成功即可
        assert!(!result.selection_set.is_empty());
        assert_eq!(result.selection_set[0].name, "createUser");
    }

    #[test]
    fn test_graphql_parser_with_variables() {
        let mut parser = GraphQLParser::new();
        let query = r#"
            query GetUser($userId: Int!) {
                user(id: $userId) {
                    name
                    email
                }
            }
        "#;

        let result = parser.parse(query).unwrap();
        assert_eq!(result.operation_type, GraphQLOperationType::Query);
        assert_eq!(result.operation_name, Some("GetUser".to_string()));
        assert!(result.variables.contains_key("userId"));
    }

    #[test]
    fn test_graphql_parser_field_alias() {
        let mut parser = GraphQLParser::new();
        let query = r#"
            query {
                allUsers: users {
                    userId: id
                    userName: name
                }
            }
        "#;

        let result = parser.parse(query).unwrap();
        assert_eq!(result.selection_set[0].alias, Some("allUsers".to_string()));
        assert_eq!(result.selection_set[0].name, "users");
        assert_eq!(result.selection_set[0].selection_set[0].alias, Some("userId".to_string()));
        assert_eq!(result.selection_set[0].selection_set[0].name, "id");
    }

    #[tokio::test]
    async fn test_memory_graphql_data_source() {
        let data_source = MemoryGraphQLDataSource::new();
        let context = GraphQLContext {
            variables: HashMap::new(),
            request_info: HashMap::new(),
        };

        // 测试用户查询
        let field = GraphQLField {
            name: "users".to_string(),
            alias: None,
            arguments: HashMap::new(),
            selection_set: vec![
                GraphQLField {
                    name: "id".to_string(),
                    alias: None,
                    arguments: HashMap::new(),
                    selection_set: vec![],
                },
                GraphQLField {
                    name: "name".to_string(),
                    alias: None,
                    arguments: HashMap::new(),
                    selection_set: vec![],
                },
            ],
        };

        let result = data_source.resolve_field(&field, &context).await.unwrap();
        assert!(result.is_array());
        let users = result.as_array().unwrap();
        assert_eq!(users.len(), 2);
    }

    #[tokio::test]
    async fn test_graphql_executor() {
        let mut executor = GraphQLExecutor::new();
        let data_source = Box::new(MemoryGraphQLDataSource::new());
        executor.register_data_source("memory".to_string(), data_source);

        let query = GraphQLQuery {
            operation_type: GraphQLOperationType::Query,
            operation_name: None,
            variables: HashMap::new(),
            selection_set: vec![
                GraphQLField {
                    name: "users".to_string(),
                    alias: None,
                    arguments: HashMap::new(),
                    selection_set: vec![
                        GraphQLField {
                            name: "id".to_string(),
                            alias: None,
                            arguments: HashMap::new(),
                            selection_set: vec![],
                        },
                        GraphQLField {
                            name: "name".to_string(),
                            alias: None,
                            arguments: HashMap::new(),
                            selection_set: vec![],
                        },
                    ],
                },
            ],
        };

        let context = GraphQLContext {
            variables: HashMap::new(),
            request_info: HashMap::new(),
        };

        let result = executor.execute(query, context).await;
        assert!(result.data.is_some());
        assert!(result.errors.is_empty());
    }

    #[tokio::test]
    async fn test_graphql_end_to_end() {
        // 解析查询
        let mut parser = GraphQLParser::new();
        let query_str = r#"
            query {
                users {
                    id
                    name
                    email
                }
            }
        "#;

        let query = parser.parse(query_str).unwrap();

        // 执行查询
        let mut executor = GraphQLExecutor::new();
        let data_source = Box::new(MemoryGraphQLDataSource::new());
        executor.register_data_source("memory".to_string(), data_source);

        let context = GraphQLContext {
            variables: HashMap::new(),
            request_info: HashMap::new(),
        };

        let result = executor.execute(query, context).await;

        // 验证结果
        assert!(result.data.is_some());
        assert!(result.errors.is_empty());

        let data = result.data.unwrap();
        assert!(data.get("users").is_some());
        let users = data.get("users").unwrap().as_array().unwrap();
        assert_eq!(users.len(), 2);

        // 验证用户数据结构
        let first_user = &users[0];
        assert!(first_user.get("id").is_some());
        assert!(first_user.get("name").is_some());
        assert!(first_user.get("email").is_some());
    }
}
